global class CaseBlacklistHandler
{
    global class CaseBlacklistException extends Exception {}
    
    public static Integer add(String Address)
    {
        List<CaseBlackList__c> addys = [Select Id, Email__c, Active__c, AutoCloseCase__c, NoAutoreply__c From CaseBlackList__c where Email__c = :Address];
        CaseBlackList__c blacklist = new CaseBlackList__c();
        Integer retSize = 0;
        if (addys.size() < 1)
        {
            // brand new email
                   
            blacklist.Email__c = Address;
            blacklist.Active__c = true;
            blacklist.AutoCloseCase__c = false;
            blacklist.NoAutoreply__c = false;
            insert blacklist;
            retSize = 1;
        }
        else
        {
            // "there can be only one!"
            blacklist = addys[0];
            update blacklist;
            syncEmailVelocityIgnore(Address, false);
        }
        
        // we now need to insert a row in the EmailVelocityIgnore object
        // the only time we can get in a bad state is if there is already a row with a non-zero threshhold
        
        List<EmailVelocityIgnore__c> nrl = EmailVelocityIgnoreHandler.get(Address, Address);
        if (nrl.size() > 0)
        {
            if (nrl[0].Threshold__c > 0)
            {
                // whoops, were screwed. This state should not exist
                String msg = 'Attempt to edit a extant record in CaseBlacklistHandler';
                System.debug(Logginglevel.ERROR, msg);
                throw new CaseBlacklistException(msg);
            }
            else
            {
                // it's there, but will cause no problems...just enable it to put it in sync with the blacklist
                EmailVelocityIgnoreHandler.enable(Address, Address, 0);
            }
        }
        else
        {
            EmailVelocityIgnoreHandler.enable(Address, Address, 0);
        }  
        
        return retSize;        
    }
    
    
    public static void edit(String Address, boolean Autoclose, boolean Noreply, boolean isActive)
    {
        List<CaseBlackList__c> addys = [Select Id, Email__c, Active__c, AutoCloseCase__c, NoAutoreply__c From CaseBlackList__c where Email__c = :Address];       
        CaseBlackList__c blacklist = new CaseBlackList__c();
        
        if (addys.size() > 0)
        {
            blacklist = addys[0];
                   
            blacklist.AutoCloseCase__c = Autoclose;
            blacklist.NoAutoreply__c = Noreply;  
            blacklist.Active__c = isActive;
            update blacklist;  
            
            // since we are piggybacking on the EmailVelocityIgnore code, we need to update that object as well
            // N.B. we insert with both the from and to addresses as the same email
            if (blacklist.Active__c)
            {
                // if we are active, then it is whatever the NoAutoreply__c is.
                syncEmailVelocityIgnore(Address, Noreply);    
            }
            else
            {
                // otherwise it is unconditionally disabled
                syncEmailVelocityIgnore(Address, false); 
            }         
        }
        else
        {
            String msg = 'Attempt to edit a non-existent record in CaseBlacklistHandler';
            System.debug(Logginglevel.INFO, msg);
        }    
    }
    
    public static void enable(String Email)
    {
        List<CaseBlackList__c> addys = [Select Id, Email__c, Active__c, AutoCloseCase__c, NoAutoreply__c From CaseBlackList__c where Email__c = :Email];
        CaseBlackList__c blacklist = new CaseBlackList__c();
        
        if (addys.size() > 0)
        {
            blacklist = addys[0];
            blacklist.Active__c = true;
            update blacklist;
            
            // if NoAutoreply__c is true, need to enable the EmailVelocityIgnore, otherwise disable it
            syncEmailVelocityIgnore(Email, blacklist.NoAutoreply__c);     
        }        
    }
    
    
    
    public static void disable(String Email)
    {
        List<CaseBlackList__c> addys = [Select Id, Email__c, Active__c, AutoCloseCase__c, NoAutoreply__c From CaseBlackList__c where Email__c = :Email];
        CaseBlackList__c blacklist = new CaseBlackList__c();
        
        if (addys.size() > 0)
        {
            blacklist = addys[0];
            blacklist.Active__c = false;
            update blacklist; 
            
            // need to disable the EmailVelocityIgnore
            syncEmailVelocityIgnore(Email, false);     
        }        
    }
    
    
    public static void syncEmailVelocityIgnore(String Email, boolean enable)
    {   
        List<EmailVelocityIgnore__c> nrl = EmailVelocityIgnoreHandler.get(Email, Email);
        if (nrl.size() < 1)
        {
            String msg = 'Case Black List attempting to edit a non-existent EmailVelocityIgnore entry: '+ Email;
            System.debug(Logginglevel.ERROR, msg);
            throw new CaseBlacklistException(msg);
        }
        else
        {
            if (nrl[0].Threshold__c > 0)
            {
                // whoops, were screwed. This state should not exist
                String msg = 'CaseBlacklistHandler attempting to sync to a non-zero threshold EmailVelocityIgnore entry: ' + Email;
                System.debug(Logginglevel.ERROR, msg);
                throw new CaseBlacklistException(msg);
            }
            else
            {
                if (enable == true)
                {
                    // need to make sure the email velocity ignore is active
                    EmailVelocityIgnoreHandler.enable(Email, Email, 0);
                }
                else
                {
                     // need to make sure the email velocity ignore is disabled
                    EmailVelocityIgnoreHandler.disable(Email, Email);
                }  
            }  
        }
    }
    
    
    public static List<CaseBlackList__c> getBlackList()
    {
        return [Select Id, Email__c, Active__c, AutoCloseCase__c, NoAutoreply__c From CaseBlackList__c];
    }
    
    public static List<CaseBlackList__c> getAutocloseActive()
    {
        return [Select Id, Email__c, Active__c, AutoCloseCase__c, NoAutoreply__c From CaseBlackList__c where AutoCloseCase__c = True];
    }
    
    public static List<CaseBlackList__c> getActive()
    {
        return [Select Id, Email__c, Active__c, AutoCloseCase__c, NoAutoreply__c From CaseBlackList__c where Active__c = True];
    }
    
    public static List<CaseBlackList__c> get(String Email)
    {
        return [Select Id, Email__c, Active__c, AutoCloseCase__c, NoAutoreply__c From CaseBlackList__c where Email__c = :Email];
    }
}